const {
    userFromdataError, userFromdataHasexist,
    userRegister, userFormNicknameExist,
    userNotExist, userPwderror,
    emailVaildtorError, eamilCodeError
} = require('../constant/errortype')

const { musicInfoExist } = require('../constant/musiclikeErrortype')
const { getUserInfo } = require('../services/UserService')

const bcrypt = require('bcryptjs/dist/bcrypt.js')
const { getRedis } = require('../utils/redis')

const multer = require('@koa/multer');
// 设置 multer 存储配置
// 配置 Multer 不保存文件，只在内存中存放
const storage = multer.memoryStorage();
const fileFilter = function (req, file, cb) {
    // 仅允许上传 png 和 jpg 类型的图片
    if (file.mimetype === 'image/png' || file.mimetype === 'image/jpeg') {
        cb(null, true); // 校验通过
    } else {
        cb(new Error('文件类型不符合要求，只允许上传 PNG 和 JPG 格式的图片'), false); // 校验不通过，拒绝上传
    }
};
//校验用户名信息是否为空
const userVaildator = async (ctx, next) => {
    try {
        const { user_email, user_password, user_nickname, code } = ctx.request.body
        if (!user_password || !user_email || !user_nickname || !code) {
            return ctx.app.emit('error', userFromdataError, ctx)
        }
        await next()
    } catch (error) {
        console.log(error);
    }

}

//检验用户账户和密码是否为空
const userInfoVaildator = async (ctx, next) => {
    const { user_email, user_password } = ctx.request.body
    if (!user_password || !user_email) {
        return ctx.app.emit('error', userFromdataError, ctx)
    }
    await next()
}
//检验用户账户和密码是否为空
const userPwdVaildator = async (ctx, next) => {
    const { oldPassword = null, user_password = null } = ctx.request.body
    if (!user_password && oldPassword || !oldPassword && user_password) {
        return ctx.app.emit('error', musicInfoExist, ctx)
    }
    await next()
}
//校验用户邮箱是否存在
const userNameVail = async (ctx, next) => {
    const { user_email } = ctx.request.body
    try {
        const res = await getUserInfo({ user_email })
        if (res)
            return ctx.app.emit('error', userFromdataHasexist, ctx)
    } catch (error) {
        console.log("用户注册信息失败", error);
        ctx.app.emit('error', userRegister, ctx)
    }

    await next()
}

//校验用户昵称是否存在
const userNicknameVaild = async (ctx, next) => {
    const { user_nickname } = ctx.request.body
    if (!user_nickname) {
        await next()
        return
    }
    try {
        const res = await getUserInfo({ user_nickname })
        if (res)
            return ctx.app.emit('error', userFormNicknameExist, ctx)
    } catch (error) {
        console.log("用户注册信息失败", error);
        ctx.app.emit('error', userRegister, ctx)
    }

    await next()
}

//密码盐值加密
const crpytPassword = async (ctx, next) => {
    const { user_password } = ctx.request.body
    if (!user_password) {
        await next()
        return
    }
    const salt = bcrypt.genSaltSync(10);
    // hash保存的是 密文
    const hash = bcrypt.hashSync(user_password, salt)
    ctx.request.body.user_password = hash

    await next();
}

//用户名校验和密码校验
const loginVaild = async (ctx, next) => {
    const { user_email, user_password } = ctx.request.body
    const result = await getUserInfo({ user_email })
    try {
        if (!result) {
            console.log(`当前${user_email}不存在`);
            return ctx.app.emit('error', userNotExist, ctx)
        }
        if (!bcrypt.compareSync(user_password, result.user_password)) {
            console.log("用户密码错误");
            return ctx.app.emit('error', userPwderror, ctx)
        }

    } catch (error) {
        console.log(error);
    }
    await next()
}

//校验用户邮箱
const emailVaildtor = async (ctx, next) => {
    try {
        const { user_email } = ctx.request.body
        const regex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
        const result = regex.test(user_email);
        if (!result) {
            console.error("邮箱格式错误");
            return ctx.app.emit('error', emailVaildtorError, ctx)
        }
        const exist = await getUserInfo({ user_email })
        if (exist) {
            console.error("邮箱已存在");
            return ctx.app.emit('error', userFromdataHasexist, ctx)
        }
        await next()
    } catch (error) {
        console.error(error);
    }
}
//校验邮箱验证码是否正确
const emailChecked = async (ctx, next) => {
    const { code, user_email } = ctx.request.body
    try {

        const result = await getRedis(user_email)
        if (code !== result) {
            return ctx.app.emit('error', eamilCodeError, ctx)
        }
        await next()
    } catch (error) {
        console.error(error);
    }


}

//校验用户信息是否为空
const userinfoVaild = async (ctx, next) => {
    const { user_nickname } = ctx.request.body
    if (!user_nickname) {
        return ctx.app.emit('error', userFromdataError, ctx)
    }
    await next()
}

//校验用户原密码
const rawPasswordVaild = async (ctx, next) => {
    const { oldPassword = null } = ctx.request.body
    if (!oldPassword) {
        return next()
    }
    const { user_id } = ctx.state.user
    const result = await getUserInfo({ user_id })
    try {
        if (!result) {
            console.log(`当前用户不存在`);
            return ctx.app.emit('error', userNotExist, ctx)
        }
        if (!bcrypt.compareSync(oldPassword, result.user_password)) {
            console.log("用户密码错误");
            return ctx.app.emit('error', userPwderror, ctx)
        }

    }
    catch (error) {

    }
    await next()
}
//查询用户原头像
const findRawimagekey = async (ctx, next) => {
    const { user_id } = ctx.state.user
    const result = await getUserInfo({ user_id })
    ctx.request.body.Oldimagekey = result.imagekey
    await next()
}

//校验用户昵称参数
const usernickname = async (ctx, next) => {
    const { user_nickname } = ctx.request.query
    if (!user_nickname) {
        return ctx.app.emit('error', userFromdataError, ctx)
    }
    await next()
}
//创建multer实例
const upload = multer({
    storage,
    fileFilter
})
const uploadFile = upload.any()

module.exports = {
    userVaildator, userNameVail,
    crpytPassword, userNicknameVaild,
    userInfoVaildator, loginVaild,
    emailVaildtor, emailChecked,
    userinfoVaild, rawPasswordVaild,
    uploadFile, findRawimagekey,
    userPwdVaildator, usernickname
}